package com.source.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.extra.qrcode.QrCodeUtil;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.source.sys.entity.User;
import com.source.sys.entity.UserRole;
import com.source.sys.mapper.UserMapper;
import com.source.sys.service.UserRoleService;
import com.source.sys.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.source.sys.vo.UserShowVo;
import com.source.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.mail.MessagingException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ZZF
 * @since 2021-02-08
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;
    @Resource
    private UserRoleService userRoleService;
    @Resource
    private EmailUtils emailUtils;


    @Override
    public Page<User> getAllUserPage(int currentPageNo, int size) {
        Page<User> userPage = new Page<>(currentPageNo,size);
        return page(userPage);
    }

    @Override
    public Page<User> getUserPageByWrapper(int currentPageNo, int size, String selectValue) {
        Page<User> userPage = new Page<>(currentPageNo,size);
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        QueryWrapper<User> likeWrapper = userQueryWrapper.like("userId", selectValue).or().like("loginName", selectValue).or().like("name", selectValue)
                .or().like("email", selectValue).or().like("mobile", selectValue);
        return page(userPage,likeWrapper);
    }

    @Deprecated
    @Override
    public Page<User> getUserPageInfo(int currentPageNo, int size) {
        Page<User> userPage = new Page<>(currentPageNo,size);
        return userPage;
    }



    @Override
    public Boolean findUserExist(String loginName) {
        User user = getOne(new QueryWrapper<User>().eq("loginName", loginName));
        if(user!=null){
            //用户存在
            return true;
        }else{
            //用户不存在
            return false;
        }
    }

    @Override
    public boolean checkEmailExist(String email) {
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("email", email));
        if(user != null){
            //存在该邮箱的用户
            return true;
        }else{
            //不存在，可用
            return false;
        }
    }

    @Override
    public void sendRegisterEmail(String email,String code) throws MessagingException {
//        //[0,1)---->[10000,100000)
//        int random = (int)(Math.random() * 100000) + 10000;
            emailUtils.sendEmail(email,code);

    }

    @Override
    public boolean checkCodeExpire(Map<String,Object> emailMap) {
        Date expireTime = (Date)emailMap.get("expireTime");
        Date now = new Date(System.currentTimeMillis());
        int compare = expireTime.compareTo(now);
        System.out.println("compare = " + compare);
        if(compare > 0){
            //compare > 0 在有效时间内，验证码有效
            return false;
        }
        return true;
    }

    @Override
    public boolean checkReceviceEmail(Map<String, Object> emailMap, String email) {
        String checkEmail = (String)emailMap.get("email");
        if(checkEmail.equals(email)){
            return true;
        }
        return false;
    }

    @Override
    public boolean checkCodeCorrect(Map<String, Object> emailMap,String emailCode) {
        String code = (String)emailMap.get("code");
        if(code.equals(emailCode)){
            //相等
            return true;
        }
        return false;
    }

    @Override
    public UserShowVo login(String loginName, String password) {
        Map<String,Object> userMap = new HashMap<String,Object>(2);
        String salt = userMapper.getSaltByLoginName(loginName);
        String key = "";
        try {
            //从数据库中获取salt值，生成密文，验证是否与数据库相同
            key = PBKDF2.getPBKDF2(password, salt);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
        userMap.put("loginName",loginName);
        userMap.put("password",key);
        User user = userMapper.selectOne(new QueryWrapper<User>().allEq(userMap));
        if(user == null){
            return null;
        }
        UserShowVo userShowVo = BeanUtil.toBean(user, UserShowVo.class);
        return userShowVo;
    }

    @Override
    public boolean register(String loginName, String password, String email) {
        int insert = userMapper.insert(new User(loginName, password, email));
        if(insert > 0){
            //注册成功
            //从用户名得到userId添加到UserRole,roleId为10011表示默认普通用户
            String getUserIdFromName = userMapper.selectOne(new QueryWrapper<User>().eq("loginName", loginName)).getUserId();
            userRoleService.addUserRole(new UserRole(getUserIdFromName,"10011"));
            return true;
        }else{
            return false;
        }
    }

    @Override
    public boolean register(String loginName, String password, String email, MultipartFile codeFile) {
        User registerUser = null;
        try {
            String salt = PBKDF2.getSalt();
            String key = PBKDF2.getPBKDF2(password, salt);
            registerUser = new User(loginName, key, email,salt);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
            return false;
        }
        //相对路径
        String wechatCodePath = "lightfowl" + File.separator + "image" + File.separator + ImageCatalogueEnum.User_Catalogue;
        //指定文件夹
        String destPath = ImageUtils.IMAGE_PATH + ImageCatalogueEnum.User_Catalogue;
        //文件名后缀
        String suffix = ".jpg";
        //给每个用户创建一个静态二维码标识  用于硬件机器登录使用
        String staticCode = UUIDUtils.getUUID20();
        registerUser.setStaticDecode(staticCode);
        //二维码文件名
        String fileName = UUID.randomUUID().toString();
        if (codeFile != null){
            //有上传文件
            String decode = null;
            try {
                //获得inputStream
                InputStream inputStream = codeFile.getInputStream();
                //解码
                decode = QrCodeUtil.decode(inputStream);
            } catch (IOException e) {
                throw new RuntimeException("二维码解析失败");
            }
            System.out.println(decode);
            registerUser.setWechatCodeDecode(decode);


            //在指定位置生成(保存)二维码
            QrCodeUtil.generate(decode,600,600 , FileUtil.file(destPath + File.separator + fileName + suffix));
            //二维码相对路径
            registerUser.setWechatCode(wechatCodePath + File.separator + fileName + suffix);

        }else{
            //未上传文件
            //先为未上传文件的用户创建一个uuid22

            String uuid22 = UUIDUtils.getUUID22();
            registerUser.setWechatCodeDecode(uuid22);
            //文件夹不存在创建文件夹
            File destDir = new File(destPath);
            if (!destDir.exists()){
                destDir.mkdirs();
            }
            //文件路径，文件保存的位置
            String filePath = destPath + File.separator + fileName + suffix;
            //二维码相对路径
            String wechatCode = wechatCodePath + File.separator + fileName + suffix;
            registerUser.setWechatCode(wechatCode);
            //生成二维码
            QrCodeUtil.generate(uuid22,600,600, FileUtil.file(filePath));
        }
        int insert = userMapper.insert(registerUser);
        if(insert > 0){
            //注册成功
            //从用户名得到userId添加到UserRole,roleId为10011表示默认普通用户
            String getUserIdFromName = userMapper.selectOne(new QueryWrapper<User>().eq("loginName", loginName)).getUserId();
            userRoleService.addUserRole(new UserRole(getUserIdFromName, (String)SysEnum.ROLEID.getData()));
            return true;
        }else{
            return false;
        }
    }

    //    @Override
//    public Boolean updateUserById(String userId,String loginName,String name,String email,String mobile) {
//        User user = userMapper.selectById(userId);
//        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
//        userUpdateWrapper.setSql("loginName = " + loginName + "and name =" + name + "and email = " + email + "and mobile = " + mobile);
//        return update(user,userUpdateWrapper);
//    }

    @Override
    public Boolean updateUserById(User user) {
        return updateById(user);
    }

    @Override
    public Boolean addUser(String loginName, String password, String name, String email, String mobile) {
        User user = new User(loginName,password,email);
        user.setName(name);
        user.setMobile(mobile);
        int insert = userMapper.insert(user);
        if(insert > 0){
            //添加成功
            //从用户名得到userId添加到UserRole,roleId为10011表示默认普通用户
            String getUserIdFromName = userMapper.selectOne(new QueryWrapper<User>().eq("loginName", loginName)).getUserId();
            userRoleService.addUserRole(new UserRole(getUserIdFromName,"10011"));
            return true;
        }else{
            //添加失败
            return false;
        }
    }

    @Override
    public boolean addUser(User user,MultipartFile multipartFile) {
        //相对路径
        String wechatCodePath = "lightfowl"+ File.separator + "image" + File.separator + ImageCatalogueEnum.User_Catalogue;
        //指定文件夹
        String destPath = ImageUtils.IMAGE_PATH + ImageCatalogueEnum.User_Catalogue;
        //文件名后缀
        String suffix = ".jpg";
        //给每个用户创建一个静态二维码标识  用于硬件机器登录使用
        String staticCode = UUIDUtils.getUUID20();
        user.setStaticDecode(staticCode);
        //二维码文件名
        String fileName = UUID.randomUUID().toString();

        if (multipartFile != null){
            System.out.println("上传文件");
            //有上传文件
            String decode = null;
            try {
                //获得inputStream
                InputStream inputStream = multipartFile.getInputStream();
                //解码
                decode = QrCodeUtil.decode(inputStream);
            } catch (IOException e) {
                throw new RuntimeException("二维码解析失败");
            }
            System.out.println(decode);
            user.setWechatCodeDecode(decode);


            //在指定位置生成(保存)二维码
            QrCodeUtil.generate(decode,600,600 , FileUtil.file(destPath + File.separator + fileName + suffix));
            //二维码相对路径
            user.setWechatCode(wechatCodePath + File.separator + fileName + suffix);
        }else{
            System.out.println("未上传文件");
            //未上传文件
            //先为未上传文件的用户创建一个uuid22

            String uuid22 = UUIDUtils.getUUID22();
            user.setWechatCodeDecode(uuid22);
            //文件夹不存在创建文件夹
            File destDir = new File(destPath);
            if (!destDir.exists()){
                destDir.mkdirs();
            }
            //文件路径，文件保存的位置
            String filePath = destPath + File.separator + fileName + suffix;
            //二维码相对路径
            String wechatCode = wechatCodePath + File.separator + fileName + suffix;
            user.setWechatCode(wechatCode);
            //生成二维码
            QrCodeUtil.generate(uuid22,600,600, FileUtil.file(filePath));
        }

        int insertResult = userMapper.insert(user);
        if(insertResult > 0){
            //注册成功
            //从用户名得到userId添加到UserRole,roleId为10011表示默认普通用户
            String getUserIdFromName = userMapper.selectOne(new QueryWrapper<User>().eq("loginName", user.getLoginName())).getUserId();
            userRoleService.addUserRole(new UserRole(getUserIdFromName, (String)SysEnum.ROLEID.getData()));
            return true;
        }else{
            return false;
        }
    }

    @Override
    public User showUserById(String userId) {
        return userMapper.selectById(userId);
    }

    @Override
    public Boolean deleteUserById(String userId) {
        return userMapper.deleteLogic(userId)>0?true:false;
    }

    @Override
    public boolean updateLoginNameAndPwd(String loginName, String password) {
        int updateResult = userMapper.updateLoginNameAndPwd(loginName, password);
        if(updateResult > 0){
            return true;
        }else {
            return false;
        }
    }

    @Override
    public List<User> findByRoleId(String roleId) {

        return userMapper.findByRoleId(roleId);
    }
}
